﻿using glb;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PIMS.Base;
using PIMS.DBModel;
using PIMS.Interface;
using PIMS.WorkPlugin.ORM;
using PIMS.WorkPlugin.Util;
using PIMS.WorkPlugin.Util.Config;
using PIMS.XmlModel;
using PIMS.YongXiang;
using PIMS_Interface.DBModel;
using PIMS_Interface.Interface;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using ZXing;
using ZXing.QrCode.Internal;
using 星瀚系统接口测试.金蝶星瀚系统.QueryCartonInfoResponse;
using 金蝶星瀚系统;
using static System.Net.Mime.MediaTypeNames;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;

namespace PIMS.WorkPlugin
{
    public class CE24056_LabelHandle : IPLCSignalHandle, IDisposable
    {
        private IDebugMsg debug = null;
        ICommunication plc = null;
        ILog4net log = null;
        int plcIndex = -1;
        int lineCount = 2;
        string plant = "";
        bool heartBit = false;
        string sLabel = "";
        //bool bWriteBox = true;

        /// <summary>
        /// PLC输入信号例子，每个输入信号要配套一个PLCSignalHandle
        /// </summary>
        private PLCSignalHandlePlus x1 = null;
        private PLCSignalHandlePlus x2 = null;
        private PLCSignalHandlePlus x3 = null;
        private PLCSignalHandlePlus x4 = null;
        private PLCSignalHandlePlus x5 = null;  //24-09-23 lff添加
        private PLCSignalHandlePlus x6 = null;  //24-10-29 lff添加
        private PLCSignalHandlePlus x7 = null;  //24-10-31 lff添加

        CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
        bool alive = false;
        bool eBoxLock = false;


        #region label实现日志分组功能
        private void DebugMsg(string Msg, InfoLevel level = InfoLevel.info)
        {
            debug.DebugMsg(Msg, LogGroup.label, level);
        }

        private void LogInfo(string message)
        {
            log.Info(message, LogGroup.label, plcIndex + 1);
        }

        private void LogError(string message)
        {
            log.Error(message, LogGroup.label, plcIndex + 1);
        }

        private void LogError(string message, Exception ex)
        {
            log.Error(message, LogGroup.label, plcIndex + 1, ex);
        }
        #endregion

        public void Init(ICommunication plc, int plcIndex, IDebugMsg debugMsg, ILog4net log4net, PIMSConfigX config)
        {
            this.plc = plc;
            //sLabel = plc.GetDeviceName().Replace("装箱", "");
            this.plcIndex = plcIndex;
            this.debug = debugMsg;
            this.log = log4net;
            this.plant = config.GetAppValueByKey("plant");

            x1 = new PLCSignalHandlePlus(label.订单结束, EventId.预留7001, debug, this.log); //扫描1完成
            //x2 = new PLCSignalHandlePlus(label.垛盘3扫描请求读取信号, EventId.预留7002, debug, this.log); //扫描2完成
            //x3 = new PLCSignalHandlePlus(label.小车1扫描请求读取信号, EventId.预留7003, debug, this.log); //扫描3完成
            //x4 = new PLCSignalHandlePlus(label.小车2扫描请求读取信号, EventId.预留7004, debug, this.log); //扫描4完成
            //x5 = new PLCSignalHandlePlus(label.堆垛1请求排垛信号, EventId.预留7005, debug, this.log); //堆垛1完成
            //x6 = new PLCSignalHandlePlus(label.堆垛2请求排垛信号, EventId.预留7006, debug, this.log); //堆垛2完成
            //x7 = new PLCSignalHandlePlus(label.垛盘4请求补标信号, EventId.预留7007, debug, this.log); //排垛完成

            if (!x1.EventBindOk)
            {
                //给输入信号绑定事件
                x1.msgHandler += new PLCSignalHandlePlus.MsgHandler(MyEventHandle);
                //x2.msgHandler += new PLCSignalHandlePlus.MsgHandler(MyEventHandle);
                //x3.msgHandler += new PLCSignalHandlePlus.MsgHandler(MyEventHandle);
                //x4.msgHandler += new PLCSignalHandlePlus.MsgHandler(MyEventHandle);
                //x5.msgHandler += new PLCSignalHandlePlus.MsgHandler(MyEventHandle);
                //x6.msgHandler += new PLCSignalHandlePlus.MsgHandler(MyEventHandle);
                //x7.msgHandler += new PLCSignalHandlePlus.MsgHandler(MyEventHandle);
            }

            
            new Task(Thread_CommicationPLC, cancelTokenSource.Token).Start();

            DebugMsg(String.Format("CE23198_LabelHandle{0} 挂载成功！", this.plcIndex));
            LogInfo(String.Format("CE23198_LabelHandle{0} 挂载成功！", this.plcIndex));

            //string zero = "".PadRight(50, '0');
        }

        public void Dispose()
        {
            try
            {
                cancelTokenSource.Cancel();
            }
            catch
            {
            }
        }

        private void Thread_CommicationPLC()
        {
            string oldMsg = "";
            while (!cancelTokenSource.IsCancellationRequested)
            {
                try
                {
                    if (plc.IsConnected)
                    {
                        if (!alive)
                        {
                            alive = true;
                            this.DebugMsg(plc.GetDeviceName() + "连接成功！", InfoLevel.info);
                            this.LogInfo(plc.GetDeviceName() + "连接成功！");
                        }
                        HandleCycle();
                    }
                    else
                    {
                        alive = false;
                        Thread.Sleep(1000);
                        plc.Connect();
                    }
                }
                catch (Exception ex)
                {
                    if (oldMsg != ex.Message)
                    {
                        oldMsg = ex.Message;
                        this.DebugMsg(oldMsg, InfoLevel.error);
                        this.LogError(oldMsg, ex);
                    }

                    plc.DisConnect();
                }
                Thread.Sleep(300);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="plc"></param>
        /// <param name="index"></param>
        public void HandleCycle()
        {
            if (plc.IsConnected)
            {

                this.heartBit = !this.heartBit;
                plc.Write<bool>(label.上位机心跳, this.heartBit);

                x1.CheckSignal(plc, plcIndex);
                //x2.CheckSignal(plc, plcIndex);
                //x3.CheckSignal(plc, plcIndex);
                //x4.CheckSignal(plc, plcIndex);
                //x5.CheckSignal(plc, plcIndex);
                //x6.CheckSignal(plc, plcIndex);
                //x7.CheckSignal(plc, plcIndex);

                ////放行信息自复位
                //bool result1, result2;
                //if (!plc.Read<bool>(label.垛盘2扫描请求读取信号, out result1) && plc.Read<bool>(label.垛盘2上位机写入完成信号, out result2)) 
                //{
                //    if (result1 && result2)
                //    {
                //        plc.Write<bool>(label.垛盘2上位机写入完成信号, false); //复位 放行信号
                //        string msg = String.Format("复位<{0}:{1}>", plc.GetDeviceName(), plc.GetItemName(label.垛盘2上位机写入完成信号));
                //        this.DebugMsg(msg);
                //        this.LogInfo(msg);
                //    }
                //}

                //if (!plc.Read<bool>(label.垛盘3扫描请求读取信号, out result1) && plc.Read<bool>(label.垛盘3上位机写入完成信号, out result2))
                //{
                //    if (result1 && result2)
                //    {
                //        plc.Write<bool>(label.垛盘3上位机写入完成信号, false); //复位 放行信号
                //        string msg = String.Format("复位<{0}:{1}>", plc.GetDeviceName(), plc.GetItemName(label.垛盘2上位机写入完成信号));
                //        this.DebugMsg(msg);
                //        this.LogInfo(msg);
                //    }
                //}

                //if (!plc.Read<bool>(label.小车1扫描请求读取信号, out result1) && plc.Read<bool>(label.小车1上位机写入完成信号, out result2)) 
                //{
                //    if (result1 && result2)
                //    {
                //        plc.Write<bool>(label.小车1上位机写入完成信号, false); //复位 放行信号
                //        string msg = String.Format("复位<{0}:{1}>", plc.GetDeviceName(), plc.GetItemName(label.小车1上位机写入完成信号));
                //        this.DebugMsg(msg);
                //        this.LogInfo(msg);
                //    }
                //}

                //if (!plc.Read<bool>(label.小车2扫描请求读取信号, out result1) && plc.Read<bool>(label.小车2上位机写入完成信号, out result2))
                //{
                //    if (result1 && result2)
                //    {
                //        plc.Write<bool>(label.小车2上位机写入完成信号, false); //复位
                //        string msg = String.Format("复位<{0}:{1}>", plc.GetDeviceName(), plc.GetItemName(label.小车2上位机写入完成信号));
                //        this.DebugMsg(msg);
                //        this.LogInfo(msg);
                //    }
                //}

                //if (!plc.Read<bool>(label.堆垛1请求排垛信号, out result1) && plc.Read<bool>(label.堆垛1允许排垛信号, out result2))
                //{
                //    if (result1 && result2)
                //    {
                //        plc.Write<bool>(label.堆垛1允许排垛信号, false); //复位 放行信号
                //        string msg = String.Format("复位<{0}:{1}>", plc.GetDeviceName(), plc.GetItemName(label.堆垛1允许排垛信号));
                //        this.DebugMsg(msg);
                //        this.LogInfo(msg);
                //    }
                //}

                //if (!plc.Read<bool>(label.堆垛2请求排垛信号, out result1) && plc.Read<bool>(label.堆垛2允许排垛信号, out result2))
                //{
                //    if (result1 && result2)
                //    {
                //        plc.Write<bool>(label.堆垛2允许排垛信号, false); //复位 放行信号
                //        string msg = String.Format("复位<{0}:{1}>", plc.GetDeviceName(), plc.GetItemName(label.堆垛2允许排垛信号));
                //        this.DebugMsg(msg);
                //        this.LogInfo(msg);
                //    }
                //}

                //if (!plc.Read<bool>(label.垛盘4请求补标信号, out result1) && plc.Read<bool>(label.垛盘4允许补标信号, out result2))
                //{
                //    if (result1 && result2)
                //    {
                //        plc.Write<bool>(label.垛盘4允许补标信号, false); //复位 放行信号
                //        string msg = String.Format("复位<{0}:{1}>", plc.GetDeviceName(), plc.GetItemName(label.垛盘4允许补标信号));
                //        this.DebugMsg(msg);
                //        this.LogInfo(msg);
                //    }
                //}

                ////是否调试电脑
                //if (System.Net.Dns.GetHostName().ToLower() == "jsjp158")
                //{
                    ////if (plc.Read<bool>(pal.上位机存在错误, out _))
                    ////{
                    ////    SimulatorBags(pal.装箱A袋信息数组);

                    ////    byte[] boxArray = new byte[pal.扫描仪反馈信息数组长度];
                    ////    byte[] b = Encoding.UTF8.GetBytes("NC123072000003");
                    ////    Array.Copy(b, boxArray, b.Length);
                    ////    plc.Write(pal.扫描仪反馈信息数组, boxArray);

                    ////    this.DebugMsg("仿真功能 写入PLC 60袋");
                    ////    plc.Write(pal.上位机存在错误, false);
                    ////}
                //}
            }
        }


        private void MyEventHandle(PlcSignalPara para)
        {
            new Thread(new ParameterizedThreadStart(Thread_HandleEvent)) { IsBackground = true }.Start(para);
        }

        /// <summary>
        /// PLC编号从0开始
        /// </summary>
        /// <param name="obj"></param>
        private void Thread_HandleEvent(object obj)
        {
            try
            {
                PlcSignalPara p = (PlcSignalPara)obj;
                string msg = String.Format("* PLC编号={0},触发事件ID=<{1}>", p.plcIndex, p.eventId.ToString());
                //  this.debug.DebugMsg(msg);
                this.LogInfo(msg);
                Thread.Sleep(500);

                switch (p.eventId)
                {
                    //case EventId.预留7001:  //套膜前扫码
                    //    string sBoxCode;
                    //    if (!ReadValue<string>(label.垛盘2对应箱号信息, "垛盘2对应箱号信息读取失败", out sBoxCode))
                    //        return;
                        
                    //    saveddata box = SqlSugarHelper.Query<saveddata>(string.Format("uid='{0}'", sBoxCode), "");
                    //    if (box != null)
                    //    {
                    //        if (string.IsNullOrEmpty(box.reserved10))
                    //        {
                    //            BoxHistory carton;
                    //            string result = KingDee.QueryCartonInfo("cartonNumber", sBoxCode, out carton);
                    //            box.reserved10 = carton.packageRule;
                    //            if (result.Contains("Err"))
                    //            {
                    //                this.LogError(string.Format("查询自动线箱信息失败!!!箱号:{0},{1}", sBoxCode, result));
                    //                this.DebugMsg(string.Format("查询自动线箱信息失败!!!箱号:{0},{1}", sBoxCode, result), InfoLevel.error);
                    //                return;
                    //            }
                    //        }
                    //        string sTmpName = box.productName + box.reserved10 + box.reserved2+box.reserved3+
                    //                            (box.uid.Length == 15 ? "1":"");
                    //        if (!WriteValue<string>(label.膜标1产品名称,"膜标1产品名称写入失败", sTmpName))
                    //            return;

                    //        int nFlag = true == string.IsNullOrEmpty(box.reserved15) ? 0 : Int32.Parse(box.reserved15);
                    //        if (!WriteValue<int>(label.膜标1套膜标志, "膜标1产品名称写入失败", nFlag))
                    //            return;

                    //        if (!WriteValue<bool>(label.垛盘2上位机写入完成信号, "垛盘2上位机写入完成信号写入失败", true))
                    //            return;
                    //    }
                    //    else
                    //    {
                    //        if (sBoxCode.Length == 14) //人工线箱
                    //        {
                    //            BoxHistory carton;
                    //            string result = KingDee.QueryCartonInfo("cartonNumber", sBoxCode, out carton);
                    //            int index = 1;
                    //            while (index <= 3)
                    //            {
                    //                if (result.Contains("Err"))
                    //                {
                    //                    int timestamp = result.Contains("未能解析此远程") ? 10000 : 3000;
                    //                    Thread.Sleep(timestamp);
                    //                    this.LogError(string.Format("尝试第{2}次查询人工线箱信息失败!!!箱号:{0},{1}", sBoxCode, result, index));
                    //                    this.DebugMsg(string.Format("尝试第{2}次查询人工线箱信息失败!!!箱号:{0},{1}", sBoxCode, result, index), InfoLevel.error);
                    //                    index++;
                    //                }
                    //                else
                    //                {
                    //                    string sTmpName = carton.materialName + carton.packageRule + carton.cusMaterialInfo;

                    //                    if (!WriteValue<string>(label.膜标1产品名称, "膜标1产品名称写入失败", sTmpName))
                    //                        return;

                    //                    if (!WriteValue<int>(label.膜标1套膜标志, "膜标1产品名称写入失败", 0))
                    //                        return;

                    //                    if (!WriteValue<bool>(label.垛盘2上位机写入完成信号, "垛盘2上位机写入完成信号写入失败", true))
                    //                        return;
                                        
                    //                    break;
                    //                }
                    //            }
                    //        }
                    //        else
                    //        {
                    //            this.DebugMsg("未找到垛盘2箱号信息,箱号：" + sBoxCode, InfoLevel.error);
                    //            this.LogError("未找到垛盘2箱号信息,箱号：" + sBoxCode);
                    //            return;
                    //        }
                    //    }

                    //    break;
                    //case EventId.预留7002:  //套膜扫码
                    //    string sBoxCode2;
                    //    if (!ReadValue<string>(label.垛盘3对应箱号信息, "垛盘3对应箱号信息读取失败", out sBoxCode2))
                    //        return;

                    //    saveddata box2 = SqlSugarHelper.Query<saveddata>(string.Format("uid='{0}'", sBoxCode2), "");
                    //    if (box2 != null)
                    //    {
                    //        string sTmpName = box2.productName + box2.reserved10 + box2.reserved2 + box2.reserved3 +
                    //                                    (box2.uid.Length == 15 ? "1" : "");

                    //        if (!WriteValue<string>(label.膜标2产品名称, "膜标2产品名称写入失败", sTmpName))
                    //            return;
                            
                    //        int nFlag = true == string.IsNullOrEmpty(box2.reserved15) ? 0 : Int32.Parse(box2.reserved15);
                    //        if (!WriteValue<int>(label.膜标2套膜标识, "膜标2套膜标志写入失败", nFlag))
                    //            return;

                    //        if (0 == nFlag)
                    //        {
                    //            string typeChinese = "";
                    //            string labelMsg = GeneralDWBoxPrintInfoFromXml(sBoxCode2, "config\\大威箱标配置.xml", out typeChinese);
                    //            if (!String.IsNullOrEmpty(labelMsg))
                    //            {
                    //                byte[] utf8Msg = Encoding.GetEncoding(typeChinese).GetBytes(labelMsg);
                    //                this.DebugMsg("发送给贴标PLC打印信息：" + typeChinese + " " + labelMsg + " 长度:" + utf8Msg.Length, InfoLevel.info);
                    //                this.LogInfo("发送给贴标PLC打印信息：" + typeChinese + " " + labelMsg + " 长度:" + utf8Msg.Length);

                    //                if (!WriteBytes(label.膜标信息, label.膜标报文信息数组长度, "写贴标数据超时,请检查通迅！", utf8Msg))
                    //                    return;
                    //                if (!WriteValue<int>(label.膜标长度, "膜标长度写入失败", utf8Msg.Length))
                    //                    return;
                    //            }
                    //            else
                    //                return;
                    //        }

                    //        if (!WriteValue<bool>(label.垛盘3上位机写入完成信号, "垛盘3上位机写入完成信号写入失败", true))
                    //            return;
                    //    }
                    //    else
                    //    {
                    //        this.DebugMsg("未找到垛盘3箱号信息,箱号：" + sBoxCode2, InfoLevel.error);
                    //        this.LogError("未找到垛盘3箱号信息,箱号：" + sBoxCode2);
                    //        return;
                    //    }
                    //    break;
                    //case EventId.预留7003:  //上小车扫码
                    //    string sBoxCode3;
                    //    if (!ReadValue<string>(label.小车1对应箱号信息, "小车1对应箱号信息读取失败", out sBoxCode3))
                    //        return;

                    //    saveddata box3 = SqlSugarHelper.Query<saveddata>(string.Format("uid='{0}'", sBoxCode3), "");
                    //    if (box3 != null)
                    //    {
                    //        string sTmpName = box3.productName + box3.reserved10 + box3.reserved2 + box3.reserved3 +
                    //                                    (box3.uid.Length == 15 ? "1" : "");

                    //        if (!WriteValue<string>(label.膜标3产品名称, "膜标3产品名称写入失败", sTmpName))
                    //            return;

                    //        if (!WriteValue<string>(label.膜标3箱号, "膜标3箱号写入失败", box3.uid))
                    //            return;

                    //        if (!WriteValue<bool>(label.小车1上位机写入完成信号, "小车1上位机写入完成信号写入失败", true))
                    //            return;
                    //    }
                    //    else
                    //    {
                    //        this.DebugMsg("未找到小车1箱号信息,箱号：" + sBoxCode3, InfoLevel.error);
                    //        this.LogError("未找到小车1箱号信息,箱号：" + sBoxCode3);
                    //        return;
                    //    }
                    //    SqlSugarHelper.UpdateRecord<saveddata>(String.Format("uid='{0}'", box3.uid),
                    //    new Dictionary<string, object>() { { "reserved15", "1" }}); //更新膜标标识

                    //    break;
                    //case EventId.预留7004:  //进堆垛扫码  
                    //    string sBoxCode4;
                    //    if (!ReadValue<string>(label.小车2对应箱号信息, "小车2对应箱号信息读取失败", out sBoxCode4))
                    //        return;

                    //    saveddata box4 = SqlSugarHelper.Query<saveddata>(string.Format("uid='{0}'", sBoxCode4), "");
                    //    if (box4 != null)
                    //    {
                    //        string sTmpName = box4.productName + box4.reserved10 + box4.reserved2 + box4.reserved3 +
                    //                                    (box4.uid.Length == 15 ? "1" : "");

                    //        if (!WriteValue<string>(label.膜标4产品名称, "膜标4产品名称写入失败", sTmpName))
                    //            return;

                    //        if (!WriteValue<string>(label.膜标4箱号, "膜标4箱号写入失败", box4.uid))
                    //            return;

                    //        if (!WriteValue<bool>(label.小车2上位机写入完成信号, "小车2上位机写入完成信号写入失败", true))
                    //            return;
                    //    }
                    //    else
                    //    {
                    //        this.DebugMsg("未找到小车2箱号信息,箱号：" + sBoxCode4, InfoLevel.error);
                    //        this.LogError("未找到小车2箱号信息,箱号：" + sBoxCode4);
                    //        return;
                    //    }
                    //    break;
                    //case EventId.预留7005:
                    //    string[] sTmps = new string[] { "", "" };

                    //    if (!ReadValue<string>(label.堆垛1箱号1, "堆垛1箱号1信息读取失败", out sTmps[0]))
                    //        return;
                    //    this.DebugMsg("堆垛1-箱号1:" + sTmps[0]);

                    //    if (!ReadValue<string>(label.堆垛1箱号2, "堆垛1箱号2信息读取失败", out sTmps[1]))
                    //        return;
                    //    this.DebugMsg("堆垛1-箱号2:" + sTmps[1]);

                    //    if (sTmps[0].Equals(sTmps[1]))
                    //    {
                    //        this.DebugMsg("堆垛1上下层箱号相同!!!箱号1:" + sTmps[0] + ",箱号2:" + sTmps[1], InfoLevel.warring);
                    //        this.LogError("堆垛1上下层箱号相同!!!箱号1:" + sTmps[0] + ",箱号2:" + sTmps[1]);
                    //        if (!ReadValue<string>(label.堆垛1箱号1, "堆垛1箱号1信息读取失败", out sTmps[0]))
                    //            return;

                    //        if (!ReadValue<string>(label.堆垛1箱号2, "堆垛1箱号2信息读取失败", out sTmps[1]))
                    //            return;
                    //    }
                    //    string palletNumber;

                    //    if (!CheckBoxInfo(sTmps, "堆垛1", out palletNumber))
                    //        return;
                    //    string sRet = "";
                    //    if (string.IsNullOrEmpty(palletNumber))
                    //    {
                    //        int nNum = 30 + Int32.Parse(sTmps[0].Substring(2, 1));
                    //        if (sTmps[0].Substring(2, 1).Equals("4"))
                    //            nNum = 31;
                    //        else
                    //            nNum = 32;
                    //        palletNumber = DJGHelper.GeneralSerialNum(nNum);
                    //        if (string.IsNullOrEmpty(palletNumber))
                    //        {
                    //            this.DebugMsg("堆垛1生成托号失败", InfoLevel.error);
                    //            this.LogError("堆垛1生成托号失败");
                    //            return;
                    //        }
                    //        sRet = KingDee.Import_CpRelation(sTmps, palletNumber);
                    //        if (sRet.Contains("Err"))
                    //        {
                    //            this.DebugMsg("堆垛1上传失败,失败原因:" + sRet, InfoLevel.error);
                    //            this.LogError("堆垛1上传失败,失败原因:" + sRet);
                    //        }
                    //    }
                        
                    //    string typeChinese_p1 = "";
                    //    string labelMsge_p1 = GeneralDWBoxPrintInfoFromXml(sTmps[0], "config\\大威托标配置.xml", out typeChinese_p1);
                    //    if (!String.IsNullOrEmpty(labelMsge_p1))
                    //    {
                    //        byte[] utf8Msg = Encoding.GetEncoding(typeChinese_p1).GetBytes(labelMsge_p1);
                    //        this.DebugMsg("发送给贴标PLC打印信息：" + typeChinese_p1 + " " + labelMsge_p1 + " 长度:" + utf8Msg.Length, InfoLevel.info);
                    //        this.LogInfo("发送给贴标PLC打印信息：" + typeChinese_p1 + " " + labelMsge_p1 + " 长度:" + utf8Msg.Length);

                    //        if (!WriteBytes(label.堆垛1托标信息, label.托标报文信息数组长度, "写堆垛1托标数据超时,请检查通迅！", utf8Msg))
                    //            return;

                    //        if (!WriteValue<int>(label.堆垛1托标长度, "堆垛1膜标长度写入失败", utf8Msg.Length))
                    //            return;
                    //    }
                    //    else
                    //        return;
                        
                    //    WriteValue<bool>(label.堆垛1允许排垛信号, "堆垛1允许排垛信号写入失败", true);

                    //    break;
                    //case EventId.预留7006:
                    //    string[] sTmp2s = new string[] { "", "" };

                    //    if (!ReadValue<string>(label.堆垛2箱号1, "堆垛2箱号1信息读取失败", out sTmp2s[0]))
                    //        return;
                    //    this.DebugMsg("堆垛2-箱号1:" + sTmp2s[0]);

                    //    if (!ReadValue<string>(label.堆垛2箱号2, "堆垛2箱号2信息读取失败", out sTmp2s[1]))
                    //        return;
                    //    this.DebugMsg("堆垛2-箱号2:" + sTmp2s[1]);

                    //    if (sTmp2s[0].Equals(sTmp2s[1]))
                    //    {
                    //        this.DebugMsg("堆垛2上下层箱号相同!!!箱号1:" + sTmp2s[0] + ",箱号2:" + sTmp2s[1], InfoLevel.warring);
                    //        this.LogError("堆垛2上下层箱号相同!!!箱号1:" + sTmp2s[0] + ",箱号2:" + sTmp2s[1]);
                    //        if (!ReadValue<string>(label.堆垛2箱号1, "堆垛2箱号1信息读取失败", out sTmp2s[0]))
                    //            return;

                    //        if (!ReadValue<string>(label.堆垛2箱号2, "堆垛2箱号2信息读取失败", out sTmp2s[1]))
                    //            return;
                    //    }

                    //    string palletNumber2;
                    //    if (!CheckBoxInfo(sTmp2s, "堆垛2", out palletNumber2))
                    //        return;
                    //    string sRet2 = "";
                    //    if (string.IsNullOrEmpty(palletNumber2))
                    //    {
                    //        int nNum = 30 + Int32.Parse(sTmp2s[0].Substring(2, 1));
                    //        if (sTmp2s[0].Substring(2, 1).Equals("4"))
                    //            nNum = 31;
                    //        else
                    //            nNum = 32; 
                    //        palletNumber2 = DJGHelper.GeneralSerialNum(nNum);
                    //        if (string.IsNullOrEmpty(palletNumber2))
                    //        {
                    //            this.DebugMsg("堆垛1生成托号失败", InfoLevel.error);
                    //            this.LogError("堆垛1生成托号失败");
                    //            return;
                    //        }
                    //        sRet2 = KingDee.Import_CpRelation(sTmp2s, palletNumber2);
                    //        if (sRet2.Contains("Err"))
                    //        {
                    //            this.DebugMsg("堆垛2上传失败,失败原因:" + sRet2, InfoLevel.error);
                    //            this.LogError("堆垛2上传失败,失败原因:" + sRet2);
                    //            return;
                    //        }
                    //    }

                    //    string typeChinese_p2 = "";
                    //    string labelMsge_p2 = GeneralDWBoxPrintInfoFromXml(sTmp2s[0], "config\\大威托标配置.xml", out typeChinese_p2);
                    //    if (!String.IsNullOrEmpty(labelMsge_p2))
                    //    {
                    //        byte[] utf8Msg = Encoding.GetEncoding(typeChinese_p2).GetBytes(labelMsge_p2);
                    //        this.DebugMsg("发送给贴标PLC打印信息：" + typeChinese_p2 + " " + labelMsge_p2 + " 长度:" + utf8Msg.Length, InfoLevel.info);
                    //        this.LogInfo("发送给贴标PLC打印信息：" + typeChinese_p2 + " " + labelMsge_p2 + " 长度:" + utf8Msg.Length);

                    //        if (!WriteBytes(label.堆垛2托标信息, label.托标报文信息数组长度, "写堆垛2托标数据超时,请检查通迅！", utf8Msg))
                    //            return;
                            
                    //        if (!WriteValue<int>(label.堆垛2托标长度, "堆垛2托标长度写入失败", utf8Msg.Length))
                    //            return;
                    //    }
                    //    else
                    //        return;

                    //    WriteValue<bool>(label.堆垛2允许排垛信号, "堆垛2允许排垛信号写入失败", true);

                    //    break;
                    //case EventId.预留7007:
                    //    string boxId;
                    //    if (!ReadValue<string>(label.垛盘4箱号, "垛盘4箱号信息读取失败", out boxId))
                    //        return;

                    //    string typeChinese_re = "";
                    //    string labelMsg_re = GeneralDWBoxPrintInfoFromXml(boxId, "config\\大威箱标配置.xml", out typeChinese_re);
                    //    if (!String.IsNullOrEmpty(labelMsg_re))
                    //    {
                    //        byte[] utf8Msg = Encoding.GetEncoding(typeChinese_re).GetBytes(labelMsg_re);
                    //        this.DebugMsg("发送给贴标PLC打印信息：" + typeChinese_re + " " + labelMsg_re + " 长度:" + utf8Msg.Length, InfoLevel.info);
                    //        this.LogInfo("发送给贴标PLC打印信息：" + typeChinese_re + " " + labelMsg_re + " 长度:" + utf8Msg.Length);

                    //        if (!WriteBytes(label.垛盘4贴标信息, label.膜标报文信息数组长度, "写垛盘4贴标数据超时,请检查通迅！", utf8Msg))
                    //            return;
                    //        if (!WriteValue<int>(label.垛盘4贴标长度, "垛盘4膜标长度写入失败", utf8Msg.Length))
                    //            return;
                    //    }
                    //    else
                    //        return;

                    //    if (!WriteValue<bool>(label.垛盘4允许补标信号, "垛盘4允许补标信号写入失败", true))
                    //        return;

                    //    break;
                    default:
                        throw new Exception($"无法识别的事件ID {p.eventId.ToString()}");
                }
            }
            catch (Exception ex)
            {
                this.LogError("", ex);
                this.DebugMsg(ex.Message, InfoLevel.error);
            }
        }

        private bool CheckBoxInfo(string[] boxcode,string devName,out string palletnumber)
        {
            palletnumber = "";
            if (boxcode[0].Equals(boxcode[1]))
            {
                this.DebugMsg(devName + "上下层箱号相同!!!箱号1:" + boxcode[0] + ",箱号2:" + boxcode[1], InfoLevel.warring);
                this.LogError(devName + "上下层箱号相同!!!箱号1:" + boxcode[0] + ",箱号2:" + boxcode[1]);
                return false;
            }
            else if (boxcode[0].Length != boxcode[1].Length)
            {
                this.DebugMsg(devName + "人工线自动线混托!!!箱号1:" + boxcode[0] + ",箱号2:" + boxcode[1], InfoLevel.warring);
                this.LogError(devName + "人工线自动线混托!!!箱号1:" + boxcode[0] + ",箱号2:" + boxcode[1]);
                return false;
            }

            saveddata box1 = SqlSugarHelper.Query<saveddata>(string.Format("uid='{0}'", boxcode[0]), "");
            if(null == box1)
            {
                this.DebugMsg("未找到"+devName+"一层箱号信息,失败原因:" + boxcode[0], InfoLevel.error);
                this.LogError("未找到"+devName+"一层箱号信息,失败原因:" + boxcode[0]);
                return false;
            }
            saveddata box2 = SqlSugarHelper.Query<saveddata>(string.Format("uid='{0}'", boxcode[1]), "");
            if (null == box2)
            {
                this.DebugMsg("未找到"+devName+"二层箱号信息,失败原因:" + boxcode[1], InfoLevel.error);
                this.LogError("未找到"+devName+"二层箱号信息,失败原因:" + boxcode[1]);
                return false;
            }
            if (box1.productName.Equals(box2.productName) && 
                box1.productMark.Equals(box2.productMark) )
            {
                if (!string.IsNullOrEmpty(box1.reserved20) ||
                    !string.IsNullOrEmpty(box2.reserved20))
                {
                    if (box1.reserved20.Equals(box2.reserved20))
                        palletnumber = box1.reserved20;
                    else
                    {
                        this.DebugMsg(devName + "上下层托号不同!!!托号1:" + box1.reserved20 + ",托号2:" + box2.reserved20, InfoLevel.warring);
                        this.LogError(devName + "上下层托号不同!!!托号1:" + box1.reserved20 + ",托号2:" + box2.reserved20);
                        return false;
                    }
                }
                return true;
            }
            else
            {
                string sRslt = string.Format("{0} + 箱信息不符,失败原因:一层料况:{1},粒径:{2}，二层料况:{3},粒径:{4}", 
                                                     devName, box1.productName,box1.productMark, box2.productName, box2.productMark);
                this.DebugMsg(sRslt, InfoLevel.error);
                this.LogError(sRslt);
                return false;
            }
        }

        private bool WriteBytes(int index,int indexLen, string errmsg, byte[] value)
        {
            byte[] msgFull = new byte[indexLen];
            Array.Copy(value, msgFull, value.Length);
            plc.Write(index, msgFull);
            byte[] msgFullRead;
            bool writeFlag = false;
            for (int i = 0; i < 5; i++)
            {
                msgFullRead = plc.Read<byte[]>(index, out _);
                if (Enumerable.SequenceEqual(msgFullRead, msgFull))
                {
                    writeFlag = true;
                    break;
                }
                else
                {
                    plc.Write(index, msgFull);
                }
                Thread.Sleep(100);
            }
            if (!writeFlag)
            {
                this.DebugMsg(errmsg, InfoLevel.error);
                this.LogError(errmsg);
            }
            return writeFlag;
        }
        private bool WriteValue<T>(int index, string errmsg, T value)
        {
            int tryCnt = 0;
            bool result2 = plc.Write<T>(index, value);
            while (!result2 && tryCnt++ < 10)
            {
                result2 = plc.Write<T>(index, value);
            }
            if (!result2)
            {
                this.DebugMsg(errmsg, InfoLevel.error);
                this.LogError(errmsg);
            }
            return result2;
        }

        private bool ReadValue<T>(int index, string errmsg, out T value)
        {
            bool result1 = false;
            int tryCnt = 0;
            value = plc.Read<T>(index, out result1);
            while (!result1 && tryCnt++ < 10)
            {
                value = plc.Read<T>(index, out result1);
                if (result1 && value is string && 
                    !string.IsNullOrEmpty(value.ToString()) && 
                    value.Equals("0"))
                {
                    result1 = false;
                }
            }
            if (!result1)
            {
                this.DebugMsg(errmsg, InfoLevel.error);
                this.LogError(errmsg);
            }
            return result1;
        }


        /// <summary>
        /// 按每袋10Kg计算总重
        /// </summary>
        /// <param name="fullCount"></param>
        /// <returns></returns>
        private string GetFullWeight(string fullCount)
        {
            int count;
            int.TryParse(fullCount, out count);
            return (count * 10).ToString();
        }

        /// <summary>
        /// 打印60袋信息到日志
        /// </summary>
        /// <param name="list"></param>
        private void Print60BagsInfo(List<string> list)
        {
            string msg = "";
            for (int i = 0; i < list.Count; i++)
            {
                msg += list[i] + " ";
                if ((i + 1) % 15 == 0)
                {
                    LogInfo(msg);
                    msg = "";
                }
            }
            if (msg != "")
            {
                LogInfo(msg);
            }
        }

        /// <summary>
        /// 依玛仕贴标数据生成
        /// 使用 依玛仕箱标配置.xml
        /// </summary>
        /// <param name="boxBarcode"></param>
        /// <returns></returns>
        private string GeneralBoxPrintInfoFromXml(string boxBarcode, out string type)
        {
            type = "";
            if (String.IsNullOrEmpty(boxBarcode))
            {
                this.DebugMsg("箱标为空！", InfoLevel.error);
                return "";
            }
            string boxPrintInfo = "";
            string cmdSql = string.Concat(new string[]
               {
                 "select * from tb_saveddata where uid='",
                  boxBarcode,
                  "'"
               });
            try
            {
                DataTable dtBox = SqlSugarHelper.QueryToDataTable<saveddata>(cmdSql);
                if (dtBox != null && dtBox.Rows.Count > 0)
                {
                    string xmlPath = AppDomain.CurrentDomain.BaseDirectory + "config\\依玛仕箱标配置.xml";
                    XmlDocument xmlDocument = new XmlDocument();
                    XmlReaderSettings settings = new XmlReaderSettings();
                    settings.IgnoreComments = true;
                    XmlReader reader = XmlReader.Create(xmlPath, settings);
                    xmlDocument.Load(reader);
                    XmlNodeList nodeList = xmlDocument.GetElementsByTagName("字段");
                    reader.Close();

                    string separator = nodeList[0].Attributes["分隔符"].Value.Replace("/r/n", Environment.NewLine); //\r\n
                    bool mark = false;
                    if (nodeList[0].Attributes["引号"].Value == "1")
                    {
                        mark = true;
                    }

                    StringBuilder data = new StringBuilder();
                    data.Append(nodeList[0].Attributes["报文头"].Value.Replace("/r/n", Environment.NewLine)); //!R
                    foreach (XmlNode item in nodeList[0].ChildNodes)
                    {
                        data.Append(item.Attributes["id"].Value); //!W1
                        string text = dtBox.Rows[0][item.Attributes["dbname"].Value].ToString().Trim();
                        if (mark) data.Append("\"");
                        if (DJGHelper.JustChinese(text))
                        {
                            type = text;
                            data.Append(DJGHelper.StringToUnicode(text)); //注：如果含中文内容，需转换为Unicode编码
                        }
                        else
                        {
                            data.Append(text);
                        }
                        data.Append(item.Attributes["tail"].Value); //Kg
                        if (mark) data.Append("\"");
                        data.Append(separator); //\r\n
                    }
                    data.Append(nodeList[0].Attributes["报文尾"].Value.Replace("/r/n", Environment.NewLine)); //!P
                    boxPrintInfo = data.ToString();
                }
                else
                {
                    this.DebugMsg("箱标对应的数据记录为空！", InfoLevel.error);
                    this.LogError(boxBarcode + "箱标对应的数据记录为空！");
                    return "";
                }
            }
            catch (Exception ex)
            {
                this.LogError(ex.Message, ex);
                return "";
            }
            return boxPrintInfo;
        }

        /// <summary>
        /// 三龙贴标数据生成
        /// 使用 三龙箱标配置.xml
        /// </summary>
        /// <param name="boxBarcode"></param>
        /// <returns></returns>
        private string GeneralThreeDragonBoxPrintInfoFromXml(string boxBarcode, out string type)
        {
            type = "";
            if (String.IsNullOrEmpty(boxBarcode))
            {
                this.DebugMsg("箱标为空！", InfoLevel.error);
                return "";
            }
            string boxPrintInfo = "";
            string cmdSql = string.Concat(new string[]
               {
                 "select * from tb_saveddata where uid='",
                  boxBarcode,
                  "'"
               });
            try
            {
                DataTable dtBox = SqlSugarHelper.QueryToDataTable<saveddata>(cmdSql);
                if (dtBox != null && dtBox.Rows.Count > 0)
                {
                    string xmlPath = AppDomain.CurrentDomain.BaseDirectory + "config\\三龙箱标配置.xml";
                    XmlDocument xmlDocument = new XmlDocument();
                    XmlReaderSettings settings = new XmlReaderSettings();
                    settings.IgnoreComments = true;
                    XmlReader reader = XmlReader.Create(xmlPath, settings);
                    xmlDocument.Load(reader);
                    XmlNodeList nodeList = xmlDocument.GetElementsByTagName("字段");
                    reader.Close();

                    StringBuilder data = new StringBuilder();
                    data.Append(nodeList[0].Attributes["报文头"].Value.Replace("/r/n", Environment.NewLine)); //!R
                    foreach (XmlNode item in nodeList[0].ChildNodes)
                    {
                        data.Append(item.Attributes["id"].Value); //!W1
                        string text = dtBox.Rows[0][item.Attributes["dbname"].Value].ToString().Trim();
                        if (item.Attributes["dbname"].Value == "型号")
                        {
                            type = text;
                            text = AutoAddPrefixBlank(text);
                        }
                        data.Append(text);
                        data.Append(item.Attributes["tail"].Value); //Kg
                    }
                    data.Append(nodeList[0].Attributes["报文尾"].Value.Replace("/r/n", Environment.NewLine)); //!P
                    boxPrintInfo = data.ToString();
                }
                else
                {
                    this.DebugMsg("箱标对应的数据记录为空！", InfoLevel.error);
                    this.LogError(boxBarcode + "箱标对应的数据记录为空！");
                    return "";
                }
            }
            catch (Exception ex)
            {
                this.LogError(ex.Message, ex);
                return "";
            }
            return boxPrintInfo;
        }
        /// <summary>
        /// 大威贴标数据生成
        /// </summary>
        /// <param name="boxBarcode"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private string GeneralDWBoxPrintInfoFromXml(string boxBarcode,string FileName, out string type)
        {
            type = "GBK";
            if (String.IsNullOrEmpty(boxBarcode))
            {
                this.DebugMsg("箱标为空！", InfoLevel.error);
                return "";
            }
            string boxPrintInfo = "";
            string cmdSql = string.Concat(new string[]
               {
                 "select * from tb_saveddata where uid='",
                  boxBarcode,
                  "'"
               });
            try
            {
                DataTable dtBox = SqlSugarHelper.QueryToDataTable<saveddata>(cmdSql);
                if (dtBox != null && dtBox.Rows.Count > 0)
                {
                    if (FileName.Contains("托标") &&(null == dtBox.Rows[0]["reserved20"] ||
                        string.IsNullOrEmpty(dtBox.Rows[0]["reserved20"].ToString())))
                    {
                        this.DebugMsg("托标为空！", InfoLevel.error);
                        this.LogError(boxBarcode + "箱标对应的托标记录为空！");
                        return "";
                    }
                    //Rootobject root = new Rootobject();
                    //root.lableIdentification = "2222";
                    //root.data = new Data();
                    //root.data.group = "";
                    //root.data.name = dtBox.Rows[0]["productName"].ToString();
                    //root.data.code = dtBox.Rows[0]["batchNo"].ToString();
                    //root.data.QRcode = boxBarcode;
                    //root.data.size = dtBox.Rows[0]["productMark"].ToString();
                    //root.data.weight = "600KG";
                    //boxPrintInfo = JsonConvert.SerializeObject(root);
                    string xmlPath = AppDomain.CurrentDomain.BaseDirectory + FileName;
                    XmlDocument xmlDocument = new XmlDocument();
                    XmlReaderSettings settings = new XmlReaderSettings();
                    settings.IgnoreComments = true;
                    XmlReader reader = XmlReader.Create(xmlPath, settings);
                    xmlDocument.Load(reader);
                    XmlNodeList nodeList = xmlDocument.GetElementsByTagName("字段");
                    reader.Close();
                    JObject jsonObject = new JObject();

                    // 添加固定属性
                    jsonObject.Add(nodeList[0].Attributes["模板字段"].Value, nodeList[0].Attributes["模板ID"].Value);
                    JObject data = new JObject();
                    // 添加动态数据
                    foreach (XmlNode item in nodeList[0].ChildNodes)
                    {
                        string sParam = item.Attributes["dbname"].Value.ToString().Trim();
                        string sValue = "";
                        if (!string.IsNullOrEmpty(sParam))
                        {
                            sValue = dtBox.Rows[0][sParam].ToString().Trim();
                        }
                        data.Add(item.Attributes["id"].Value, sValue + item.Attributes["tail"].Value.Trim());
                    }

                    jsonObject.Add(nodeList[0].Attributes["内容字段"].Value, data);
                    boxPrintInfo = JsonConvert.SerializeObject(jsonObject);
                }
                else
                {
                    this.DebugMsg("箱标对应的数据记录为空！", InfoLevel.error);
                    this.LogError(boxBarcode + "箱标对应的数据记录为空！");
                    return "";
                }
            }
            catch (Exception ex)
            {
                this.LogError(ex.Message, ex);
                return "";
            }
            return boxPrintInfo;
        }
        /// <summary>
        /// 自动加前缀空格，用于袋标、箱标型号居中
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        private string AutoAddPrefixBlank(string name, int length = 8)
        {
            string result = name;
            if (name.Length < length)
            {
                for (int i = 0; i < (length - name.Length) / 2; i++)
                {
                    result = " " + result;
                }
            }
            return result;
        }

    }
}
